package com.hank.tetris;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

import static java.lang.Boolean.TRUE;

/*
    绘制图形
 */
public class Tetris extends JPanel {

    public static final int CELL_UNIT =27;
    //X坐标 对应列
    public static final int COL_NUM=10;
    //Y坐标 对应行
    public static final int ROW_NUM = 20;

    //绘图重点,将点变成二维,绘制地图
    private Cell[][] panelCells= new Cell[ROW_NUM][COL_NUM];

    public Tetromino tetromino=Tetromino.getOne();//当前下降的格子
    public Tetromino nextOne=Tetromino.getOne();//下一个下降的格子

    private int score;//分数
    private int lines;//行数

    private Timer timer;//定时调度时间
    private static final int MAXSPEEDUNIX =40;
    private int speedunix;//速度
    private int level=1;//等级
    private int index;//相当于计时器

    private int state;//游戏状态
    private static final int RUNNING=0;
    private static final int PAUSE = 1;
    private static final int GAME_OVER = 2;

    /**
     * 绘制背景墙
     * @param g
     */
    public void paintPanelCells(Graphics g){
        for(int i=0;i<panelCells.length;i++){
            for(int j=0;j<panelCells[i].length;j++){
                Cell cell =  new Cell(i,j,Color.WHITE);
                cell.paint(g);
            }
        }
    }

    //绘制背景
    public void paintWallCells(Graphics g){
        for(int i=0;i<panelCells.length;i++){
            for(int j=0;j<panelCells[i].length;j++){
                if(panelCells[i][j] != null){
                    panelCells[i][j].paint(g);
                }
            }
        }
    }

    /**
     * 当前下降的格子
     * @param g
     */
    public void paintTetromino(Graphics g){
        if(tetromino == null){
            return;//结束方法
        }
        for(int i=0;i<tetromino.cells.length;i++){
            tetromino.cells[i].paint(g);
        }
    }

    @Override
    public void paint(Graphics g){
        super.paint(g);
        //绘制背景墙
        paintPanelCells(g);
        //绘制墙
        paintWallCells(g);
        //画正在落下
        paintTetromino(g);
    }

    /**
     * 判断是否重合
     * @return
     */
    private boolean coinclude(){
        Cell[] cells = tetromino.cells;
        for (int i = 0; i < cells.length; i++) {
            Cell cell = cells[i];
            int row = cell.getRow();
            int col = cell.getCol();
            if (panelCells[row][col] != null) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否出界
     * @return
     */
    private boolean outOfBounds(){
        Cell[] cells = tetromino.cells;
        for(int i=0;i<cells.length;i++){
            Cell cell = cells[i];
            int col = cell.getCol();
            if(col <0 || col >= COL_NUM){
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否可以下降
     * @return
     */
    private boolean canDrop(){
        Cell[] cells = tetromino.cells;
        //到达最后一行
        for(int i=0;i<cells.length;i++){
            Cell cell = cells[i];
            int row =cell.getRow();
            if(row == ROW_NUM - 1){
                return false;
            }
        }
        //下一行有格子  可以优化的点
        for(Cell cell:cells){
            int row = cell.getRow() + 1;
            int col = cell.getCol();
            if(panelCells[row][col] != null){
                return false;
            }
        }
        return true;
    }

    /**
     * 判断行数是否已满
     * @return
     */
    private boolean fullCells(int row){
        Cell[] line = panelCells[row];//获取每一个格子的行
        for(Cell cell:line){
            if(cell == null){
                return false;
            }
        }
        return true;
    }

    /**
     * 判断游戏是否结束
     * @return
     */
    private boolean isGameOver(){
        Cell[] cells = nextOne.cells;
        for(Cell cell:cells){
            int row = cell.getRow();
            int col = cell.getCol();
            if(panelCells[row][col] != null){
                return true;
            }
        }
        return false;
    }

    //右移行为
    private void moveRightAction(){
        //判断是否出界
        tetromino.moveRight();
        if (this.outOfBounds() || this.coinclude()) {
            tetromino.moveLeft();
        }
    }

    //左移行为
    private void moveLeftAction(){
        //判断是否出界
        tetromino.moveLeft();
        if (this.outOfBounds() || this.coinclude()){
            tetromino.moveRight();
        }
    }

    //下落行为
    public void softDorpAction(){
        if(this.canDrop()){
            tetromino.softDorp();
        }else{
            //游戏结束
            if(this.isGameOver()){
                this.state = GAME_OVER;
                panelCells= new Cell[ROW_NUM][COL_NUM];
            }
            this.landIntoWall();
            this.destoryLines();
            this.tetromino = this.nextOne;
            this.nextOne = Tetromino.getOne();
        }
    }

    private void hardDropAction(){
        while (this.canDrop()){
            tetromino.softDorp();
        }
    }

    //翻转行为
    private void rotateRightAcition(){
        tetromino.roateRight();
        if(this.outOfBounds() || this.coinclude()){
            tetromino.roateLeft();
        }
    }

    //着地行为
    public void landIntoWall(){
        //获取正在下落的四个格子
        Cell[] cells = tetromino.cells;
        for(int i = 0; i< cells.length; i++){
            Cell cell = cells[i];
            int row = cell.getRow();
            int col = cell.getCol();
            panelCells[row][col] = cell;
        }
    }

    //销毁行
    public void destoryLines(){
        //要更新行
        for(int i=0;i < tetromino.cells.length;i++){
            int row = tetromino.cells[i].getRow();
            if(this.fullCells(row)){
                this.deleteRow(row);
            }
        }
    }

    /**
     * 删除行
     */
     public void deleteRow(int row)    {
         for(int i = row; i >=1; i--) {
             panelCells[i] = panelCells[i-1];
             for(int j=0;j<COL_NUM;j++){
                 if(panelCells[i][j] != null){
                     panelCells[i][j].setRow(i);
                 }
             }
         }
         panelCells[0]=new Cell[COL_NUM];
     }


    /**
     * 运行按钮
     * @param keyCode
     */
    private void processRunningKey(int keyCode){
        switch (keyCode){
            case KeyEvent.VK_Q:
                System.exit(0);
                break;
            case KeyEvent.VK_LEFT:
                System.out.println("向左");//向左移动
                moveLeftAction();
                break;
            case KeyEvent.VK_RIGHT:
                System.out.println("向右");//向右移动
                moveRightAction();
                break;
            case KeyEvent.VK_UP:
                System.out.println("向上");//翻转
                rotateRightAcition();
                break;
            case KeyEvent.VK_DOWN:
                System.out.println("向下");//加速
                hardDropAction();
                break;
            case KeyEvent.VK_SPACE:
                this.state = PAUSE;
                break;
            case KeyEvent.VK_P:
                this.state = PAUSE;
                break;
        }
    }

    /**
     * 停止按钮
     * @param keyCode
     */
    private void processPauseKey(int keyCode){
        switch (keyCode){
            case KeyEvent.VK_Q:
                System.exit(0);
                break;
            case KeyEvent.VK_C:
                this.state=RUNNING;
                break;
        }
    }

    private void processGameOverKey(int keyCode){
        switch (keyCode){
            case KeyEvent.VK_Q:
                System.exit(0);
                break;
            case KeyEvent.VK_S:

                break;
        }
    }

    public void action(){
        //设置游戏状态
        this.state = RUNNING;

        KeyAdapter l = new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                super.keyReleased(e);
                int keyCode =e.getKeyCode();
                switch (state){
                    case RUNNING:
                        processRunningKey(keyCode);
                        break;
                    case PAUSE:
                    case GAME_OVER:
                }
                repaint();
            }
        };

        this.requestFocus();
        this.addKeyListener(l);

        //定时任务去跑
        this.timer = new Timer();
        this.timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //速度是40档
                speedunix = MAXSPEEDUNIX -(lines /2);
                speedunix = speedunix < 1 ? 1 : speedunix;
                level = MAXSPEEDUNIX+1 - speedunix;
//                System.out.println("speed："+speedunix+";index："+index+";"+"%："+index % speedunix+";");
                if(state == RUNNING && index % speedunix == 0) {
                    softDorpAction();
                }
                index++;
                repaint();
            }
        },10,13);
    }

    public static void main(String[] args) {
        JFrame jFrame = new JFrame("俄罗斯方块v1.0");
        Tetris tetris = new Tetris();
        jFrame.setSize(450,580);
        jFrame.setLocationRelativeTo(null);
        jFrame.setResizable(true);
        jFrame.setDefaultCloseOperation(jFrame.EXIT_ON_CLOSE);
        jFrame.add(tetris);
        jFrame.setVisible(true);
        tetris.action();

    }
}
